home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / SHK.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  44KB  |  1,644 lines

  1. /*    SCCS Id: @(#)shk.c    3.0    89/11/27
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #define MONATTK_H    /* comment line for pre-compiled headers */
  6. /* block some unused #defines to avoid overloading some cpp's */
  7. #include "hack.h"
  8.  
  9. #include "eshk.h"
  10.  
  11.  
  12. # ifdef KOPS
  13. STATIC_DCL int FDECL(makekops, (coord *));
  14. # ifdef OVLB
  15. static void NDECL(kops_gone);
  16. # endif /* OVLB */
  17. #endif /* KOPS */
  18.  
  19. #define    NOTANGRY(mon)    mon->mpeaceful
  20. #define    ANGRY(mon)    !NOTANGRY(mon)
  21.  
  22. /* Descriptor of current shopkeeper. Note that the bill need not be
  23.    per-shopkeeper, since it is valid only when in a shop. */
  24. STATIC_VAR struct monst NEARDATA *shopkeeper;
  25. STATIC_VAR struct bill_x NEARDATA *bill;
  26. STATIC_VAR int NEARDATA shlevel; /* level of this shopkeeper */
  27. /* struct obj *billobjs;    /* objects on bill with bp->useup */
  28.                 /* only accessed here and by save & restore */
  29. STATIC_VAR long int NEARDATA total;     /* filled by addupbill() */
  30. STATIC_VAR long int NEARDATA followmsg;    /* last time of follow message */
  31.  
  32. STATIC_DCL void NDECL(setpaid);
  33. STATIC_DCL void NDECL(addupbill);
  34. STATIC_DCL boolean FDECL(monstinroom, (struct permonst *,int));
  35. STATIC_DCL void FDECL(findshk, (int));
  36.  
  37. #ifdef OVLB
  38.  
  39. static struct bill_x * FDECL(onbill, (struct obj *));
  40. static long FDECL(check_credit, (long,struct monst *));
  41. static void FDECL(pay, (long,struct monst *));
  42. static unsigned FDECL(get_cost, (struct obj *));
  43. static unsigned FDECL(cost_per_charge, (struct obj *));
  44. static int FDECL(dopayobj, (struct bill_x *)), FDECL(getprice, (struct obj *));
  45. static struct obj *FDECL(bp_to_obj, (struct bill_x *));
  46.  
  47. /*
  48.     invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
  49.         obj->quan <= bp->bquan
  50.  */
  51.  
  52. char *
  53. shkname(mtmp)                /* called in do_name.c */
  54. register struct monst *mtmp;
  55. {
  56.     return(ESHK(mtmp)->shknam);
  57. }
  58.  
  59. void
  60. shkdead(mtmp)                /* called in mon.c */
  61. register struct monst *mtmp;
  62. {
  63.     register struct eshk *eshk = ESHK(mtmp);
  64.  
  65.     if(eshk->shoplevel == dlevel)
  66.         rooms[eshk->shoproom].rtype = OROOM;
  67.     if(mtmp == shopkeeper) {
  68.         setpaid();
  69.         shopkeeper = 0;
  70.         bill = (struct bill_x *) -1000;    /* dump core when referenced */
  71.     }
  72. }
  73.  
  74. void
  75. replshk(mtmp,mtmp2)
  76. register struct monst *mtmp, *mtmp2;
  77. {
  78.     if(mtmp == shopkeeper) {
  79.         shopkeeper = mtmp2;
  80.         bill = &(ESHK(shopkeeper)->bill[0]);
  81.     }
  82. }
  83.  
  84. STATIC_OVL void
  85. setpaid(){    /* caller has checked that shopkeeper exists */
  86.         /* either we paid or left the shop or he just died */
  87.     register struct obj *obj;
  88.     register struct monst *mtmp;
  89.     for(obj = invent; obj; obj = obj->nobj)
  90.         obj->unpaid = 0;
  91.     for(obj = fobj; obj; obj = obj->nobj)
  92.         obj->unpaid = 0;
  93.     for(obj = fcobj; obj; obj = obj->nobj)
  94.         obj->unpaid = 0;
  95.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  96.         for(obj = mtmp->minvent; obj; obj = obj->nobj)
  97.             obj->unpaid = 0;
  98.     for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
  99.         for(obj = mtmp->minvent; obj; obj = obj->nobj)
  100.             obj->unpaid = 0;
  101.     while(obj = billobjs){
  102.         billobjs = obj->nobj;
  103.         free((genericptr_t) obj);
  104.     }
  105.     if(shopkeeper) {
  106.         ESHK(shopkeeper)->billct = 0;
  107.         ESHK(shopkeeper)->credit = 0L;
  108.         ESHK(shopkeeper)->debit = 0L;
  109.     }
  110. }
  111.  
  112. STATIC_OVL void
  113. addupbill(){    /* delivers result in total */
  114.         /* caller has checked that shopkeeper exists */
  115.     register int ct = ESHK(shopkeeper)->billct;
  116.     register struct bill_x *bp = bill;
  117.     total = 0;
  118.     while(ct--){
  119.         total += bp->price * bp->bquan;
  120.         bp++;
  121.     }
  122. }
  123.  
  124. STATIC_OVL boolean
  125. monstinroom(mdat,roomno)
  126. struct permonst *mdat;
  127. int roomno;
  128. {
  129.     register struct monst *mtmp;
  130.  
  131.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  132.         if(mtmp->data == mdat && inroom(mtmp->mx,mtmp->my) == roomno)
  133.             return(TRUE);
  134.     return(FALSE);
  135. }
  136.  
  137. #endif /* OVLB */
  138. #ifdef OVL1
  139.  
  140. int
  141. inshop() {
  142.     register int roomno = inroom(u.ux,u.uy);
  143.  
  144.     /* Did we just leave a shop? */
  145.     if(u.uinshop &&
  146.         (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
  147.  
  148.     /* This is part of the bugfix for shopkeepers not having their
  149.      * bill paid.  As reported by ab@unido -dgk
  150.      * I made this standard due to the KOPS code below. -mrs
  151.      */
  152.         if(shopkeeper) {
  153.             if(ESHK(shopkeeper)->billct || ESHK(shopkeeper)->debit) {
  154.             if(inroom(shopkeeper->mx, shopkeeper->my)
  155.                 == u.uinshop - 1)    /* ab@unido */
  156.                 You("escaped the shop without paying!");
  157.             addupbill();
  158.             total += ESHK(shopkeeper)->debit;
  159.             You("stole %ld zorkmid%s worth of merchandise.",
  160.                 total, plur(total));
  161.             ESHK(shopkeeper)->robbed += total;
  162.             ESHK(shopkeeper)->credit = 0L;
  163.             ESHK(shopkeeper)->debit = 0L;
  164.             if (pl_character[0] != 'R') /* stealing is unlawful */
  165.                 adjalign(-sgn(u.ualigntyp));
  166.             setpaid();
  167.             if((rooms[ESHK(shopkeeper)->shoproom].rtype == SHOPBASE)
  168.                 == (rn2(3) == 0))
  169.                 ESHK(shopkeeper)->following = 1;
  170. #ifdef KOPS
  171.             {   /* Keystone Kops srt@ucla */
  172.             coord mm;
  173.  
  174.             if (flags.soundok)
  175.                 pline("An alarm sounds throughout the dungeon!");
  176.             if(flags.verbose) {
  177.                 if((mons[PM_KEYSTONE_KOP].geno & G_GENOD) &&
  178.                     (mons[PM_KOP_SERGEANT].geno & G_GENOD) &&
  179.                     (mons[PM_KOP_LIEUTENANT].geno & G_GENOD) &&
  180.                    (mons[PM_KOP_KAPTAIN].geno & G_GENOD)) {
  181.                 if (flags.soundok)
  182.                     pline("But no one seems to respond to it.");
  183.                 } else
  184.                 pline("The Keystone Kops are after you!");
  185.             }
  186.             /* Create a swarm near the staircase */
  187.             mm.x = xdnstair;
  188.             mm.y = ydnstair;
  189.             (void) makekops(&mm);
  190.             /* Create a swarm near the shopkeeper */
  191.             mm.x = shopkeeper->mx;
  192.             mm.y = shopkeeper->my;
  193.             (void) makekops(&mm);
  194.             }
  195. #endif
  196.             }
  197.             shopkeeper = 0;
  198.             shlevel = 0;
  199.         }
  200.         u.uinshop = 0;
  201.     }
  202.  
  203.     /* Did we just enter a zoo of some kind? */
  204.     /* This counts everything except shops and vaults
  205.        -- vault.c insists that a vault remain a VAULT */
  206.     if(roomno >= 0) {
  207.         register int rt = rooms[roomno].rtype;
  208.         register struct monst *mtmp;
  209.  
  210.         switch (rt) {
  211.         case ZOO:
  212.             pline("Welcome to David's treasure zoo!");
  213.             break;
  214.         case SWAMP:
  215.             pline("It looks rather muddy down here.");
  216.             break;
  217. #ifdef THRONES
  218.         case COURT:
  219.             You("enter an opulent throne room!");
  220.             break;
  221. #endif
  222.         case MORGUE:
  223.             if(midnight())
  224.             pline("Run away!  Run away!");
  225.             else
  226.             You("have an uncanny feeling...");
  227.             break;
  228.         case BEEHIVE:
  229.             You("enter a giant beehive!");
  230.             break;
  231. #ifdef ARMY
  232.         case BARRACKS:
  233.             if(monstinroom(&mons[PM_SOLDIER], roomno) ||
  234.                 monstinroom(&mons[PM_SERGEANT], roomno) ||
  235.                 monstinroom(&mons[PM_LIEUTENANT], roomno) ||
  236.                 monstinroom(&mons[PM_CAPTAIN], roomno))
  237.                 You("enter a military barracks!");
  238.             else You("enter an abandoned barracks.");
  239.             break;
  240. #endif
  241. #ifdef ORACLE
  242.         case DELPHI:
  243.             if(monstinroom(&mons[PM_ORACLE], roomno))
  244.                 pline("\"Hello, %s, welcome to Delphi!\"", plname);
  245.             break;
  246. #endif
  247.         default:
  248.             rt = 0;
  249.         }
  250.  
  251.         if(rt != 0) {
  252.             rooms[roomno].rtype = OROOM;
  253.             if(rt==COURT || rt==SWAMP || rt==MORGUE || rt==ZOO)
  254.             for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  255.                 /* was if(rt != ZOO || !rn2(3)) -- why should ZOO
  256.                    be different from COURT or MORGUE? */
  257.                 if(!Stealth && !rn2(3))
  258.                 mtmp->msleep = 0;
  259.         }
  260.     }
  261. #if defined(ALTARS) && defined(THEOLOGY)
  262.     if(roomno >= 0 && rooms[roomno].rtype == TEMPLE) {
  263.         intemple();
  264.     }
  265. #endif
  266.     /* Did we just enter a shop? */
  267.     if(roomno >= 0 && rooms[roomno].rtype >= SHOPBASE) {
  268.         register int rt = rooms[roomno].rtype;
  269.  
  270.         if(shlevel != dlevel || !shopkeeper
  271.                  || ESHK(shopkeeper)->shoproom != roomno)
  272.         findshk(roomno);
  273.         if(!shopkeeper) {
  274.         rooms[roomno].rtype = OROOM;
  275.         u.uinshop = 0;
  276.         } else if(!u.uinshop){
  277.         if(!ESHK(shopkeeper)->visitct ||
  278.            strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) {
  279.             /* He seems to be new here */
  280.             ESHK(shopkeeper)->visitct = 0;
  281.             ESHK(shopkeeper)->following = 0;
  282.             (void) strncpy(ESHK(shopkeeper)->customer,plname,PL_NSIZ);
  283.             NOTANGRY(shopkeeper) = 1;
  284.         }
  285.         if(!ESHK(shopkeeper)->following && inhishop(shopkeeper)) {
  286.             if(Invis) {
  287.             pline("%s senses your presence.", shkname(shopkeeper));
  288.             verbalize("Invisible customers are not welcome!");
  289.             }
  290.             else
  291.             if(ANGRY(shopkeeper))
  292.             pline("\"So, %s, you dare return to %s's %s?!\"",
  293.                 plname,
  294.                 shkname(shopkeeper),
  295.                 shtypes[rt - SHOPBASE].name);
  296.             else
  297.             if(ESHK(shopkeeper)->robbed)
  298.             pline("\"Beware, %s!  I am upset about missing stock!\"",
  299.                 plname);
  300.             else
  301.             pline("\"Hello, %s!  Welcome%s to %s's %s!\"",
  302.                 plname,
  303.                 ESHK(shopkeeper)->visitct++ ? " again" : "",
  304.                 shkname(shopkeeper),
  305.                 shtypes[rt - SHOPBASE].name);
  306.             if(carrying(PICK_AXE) != (struct obj *)0 && !Invis) {
  307.             verbalize(NOTANGRY(shopkeeper) ?
  308.                "Will you please leave your pick-axe outside?" :
  309.                "Leave the pick-axe outside.");
  310.             if(dochug(shopkeeper)) {
  311.                 u.uinshop = 0;    /* he died moving */
  312.                 return(0);
  313.             }
  314.             }
  315.         }
  316.         u.uinshop = (unsigned int)(roomno + 1);
  317.         }
  318.     }
  319.     return (int)u.uinshop;
  320. }
  321.  
  322. #endif /* OVL1 */
  323. #ifdef OVLB
  324.  
  325. int
  326. inhishop(mtmp)
  327. register struct monst *mtmp;
  328. {
  329.     return((ESHK(mtmp)->shoproom == inroom(mtmp->mx, mtmp->my) &&
  330.         ESHK(mtmp)->shoplevel == dlevel));
  331. }
  332.  
  333. #ifdef SOUNDS
  334. boolean
  335. tended_shop(sroom)
  336. struct mkroom *sroom;
  337. {
  338.     register struct monst *mtmp;
  339.  
  340.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  341.         if(mtmp->isshk && &rooms[ESHK(mtmp)->shoproom] == sroom
  342.         && inhishop(mtmp)) return(TRUE);
  343.     return(FALSE);
  344. }
  345. #endif
  346.  
  347. STATIC_OVL void
  348. findshk(roomno)
  349. register int roomno;
  350. {
  351.     register struct monst *mtmp;
  352.  
  353.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  354.         if(mtmp->isshk && ESHK(mtmp)->shoproom == roomno
  355.                && ESHK(mtmp)->shoplevel == dlevel) {
  356.         shopkeeper = mtmp;
  357.         bill = &(ESHK(shopkeeper)->bill[0]);
  358.         shlevel = dlevel;
  359.         if(ANGRY(shopkeeper) &&
  360.            strncmp(ESHK(shopkeeper)->customer,plname,PL_NSIZ))
  361.             NOTANGRY(shopkeeper) = 1;
  362.         /* billobjs = 0; -- this is wrong if we save in a shop */
  363.         /* (and it is harmless to have too many things in billobjs) */
  364.         return;
  365.     }
  366.     shopkeeper = 0;
  367.     shlevel = 0;
  368.     bill = (struct bill_x *) -1000;    /* dump core when referenced */
  369. }
  370.  
  371. static struct bill_x *
  372. onbill(obj)
  373. register struct obj *obj;
  374. {
  375.     register struct bill_x *bp;
  376.     if(!shopkeeper) return (struct bill_x *)0;
  377.     for(bp = bill; bp < &bill[ESHK(shopkeeper)->billct]; bp++)
  378.         if(bp->bo_id == obj->o_id) {
  379.             if(!obj->unpaid) pline("onbill: paid obj on bill?");
  380.             return(bp);
  381.         }
  382.     if(obj->unpaid) pline("onbill: unpaid obj not on bill?");
  383.     return (struct bill_x *)0;
  384. }
  385.  
  386. /* called with two args on merge */
  387. void
  388. obfree(obj, merge)
  389. register struct obj *obj, *merge;
  390. {
  391.     register struct bill_x *bp = onbill(obj);
  392.     register struct bill_x *bpm;
  393.     if(bp) {
  394.         if(!merge){
  395.             bp->useup = 1;
  396.             obj->unpaid = 0;    /* only for doinvbill */
  397.             obj->nobj = billobjs;
  398.             billobjs = obj;
  399.             return;
  400.         }
  401.         bpm = onbill(merge);
  402.         if(!bpm){
  403.             /* this used to be a rename */
  404.             impossible("obfree: not on bill??");
  405.             return;
  406.         } else {
  407.             /* this was a merger */
  408.             bpm->bquan += bp->bquan;
  409.             ESHK(shopkeeper)->billct--;
  410.             *bp = bill[ESHK(shopkeeper)->billct];
  411.         }
  412.     }
  413.     free((genericptr_t) obj);
  414. }
  415.  
  416. static long
  417. check_credit(tmp, shkp)
  418. long tmp;
  419. register struct monst *shkp;
  420. {
  421.     long credit = ESHK(shkp)->credit;
  422.  
  423.     if(credit == 0L) return(tmp);
  424.     if(credit >= tmp) {
  425.         pline("The price is deducted from your credit.");
  426.         ESHK(shkp)->credit -=tmp;
  427.         tmp = 0L;
  428.     } else {
  429.         pline("The price is partially covered by your credit.");
  430.         ESHK(shkp)->credit = 0L;
  431.         tmp -= credit;
  432.     }
  433.     return(tmp);
  434. }
  435.  
  436. static void
  437. pay(tmp,shkp)
  438. long tmp;
  439. register struct monst *shkp;
  440. {
  441.     long robbed = ESHK(shkp)->robbed;
  442.     long balance = ((tmp <= 0L) ? tmp : check_credit(tmp, shkp));
  443.  
  444.     u.ugold -= balance;
  445.     shkp->mgold += balance;
  446.     flags.botl = 1;
  447.     if(robbed) {
  448.         robbed -= tmp;
  449.         if(robbed < 0) robbed = 0L;
  450.         ESHK(shkp)->robbed = robbed;
  451.     }
  452. }
  453.  
  454. /* return shkp to home position */
  455. void
  456. home_shk(shkp)
  457. register struct monst *shkp;
  458. {
  459.     register xchar x = ESHK(shkp)->shk.x, y = ESHK(shkp)->shk.y;
  460.     if(MON_AT(x, y))
  461.         mnearto(m_at(x,y), x, y, FALSE);
  462.     remove_monster(shkp->mx, shkp->my);
  463.     place_monster(shkp, x, y);
  464.     unpmon(shkp);
  465. }
  466.  
  467. void
  468. make_happy_shk(shkp)
  469. struct monst *shkp;
  470. {
  471.     register boolean wasmad = ANGRY(shkp);
  472.  
  473.     NOTANGRY(shkp) = 1;
  474.     ESHK(shkp)->following = 0;
  475.     ESHK(shkp)->robbed = 0L;
  476.     if (pl_character[0] != 'R')
  477.         adjalign(sgn(u.ualigntyp));
  478.     if(!inhishop(shkp)) {
  479.         pline("Satisfied, %s suddenly disappears!", mon_nam(shkp));
  480.         if(ESHK(shkp)->shoplevel == dlevel)
  481.             home_shk(shkp);
  482.         else
  483.             fall_down(shkp, ESHK(shkp)->shoplevel);
  484.     } else if(wasmad)
  485.         pline("%s calms down.", Monnam(shkp));
  486. #ifdef KOPS
  487.     kops_gone();
  488. #endif
  489. }
  490.  
  491. static const char no_money[] = "Moreover, you have no money.";
  492.  
  493. int
  494. dopay()
  495. {
  496.     long ltmp;
  497.     register struct bill_x *bp;
  498.     register struct monst *shkp;
  499.     int pass, tmp;
  500.  
  501.     multi = 0;
  502.     (void) inshop();
  503.     for(shkp = fmon; shkp; shkp = shkp->nmon)
  504.         if(shkp->isshk && dist(shkp->mx,shkp->my) < 3)
  505.             break;
  506.     if(!shkp && u.uinshop && inhishop(shopkeeper))
  507.         shkp = shopkeeper;
  508.  
  509.     if(!shkp) {
  510.         pline("There is nobody here to receive your payment.");
  511.         return(0);
  512.     }
  513.     ltmp = ESHK(shkp)->robbed;
  514.     if(shkp != shopkeeper && NOTANGRY(shkp)) {
  515.         if(!ltmp)
  516.             You("do not owe %s anything.", mon_nam(shkp));
  517.         else if(!u.ugold)
  518.             You("have no money.");
  519.         else {
  520.             long ugold = u.ugold;
  521.  
  522.             if(ugold > ltmp) {
  523.             You("give %s the %ld gold piece%s %s asked for.",
  524.                 mon_nam(shkp), ltmp, plur(ltmp),
  525.                 ESHK(shkp)->ismale ? "he" : "she");
  526.             pay(ltmp, shkp);
  527.             } else {
  528.             You("give %s all your gold.", mon_nam(shkp));
  529.             pay(u.ugold, shkp);
  530.             }
  531.             if(ugold < ltmp/2L)
  532.             pline("Unfortunately, %s doesn't look satisfied.",
  533.                 ESHK(shkp)->ismale ? "he" : "she");
  534.             else
  535.             make_happy_shk(shkp);
  536.         }
  537.         return(1);
  538.     }
  539.  
  540.     /* ltmp is still ESHK(shkp)->robbed here */
  541.     if(!ESHK(shkp)->billct && !ESHK(shkp)->debit) {
  542.         if(!ltmp && NOTANGRY(shkp)) {
  543.             You("do not owe %s anything.", mon_nam(shkp));
  544.             if(!u.ugold) pline(no_money);
  545.         } else if(ltmp) {
  546.             pline("%s is after blood, not money!", mon_nam(shkp));
  547.             if(u.ugold < ltmp/2L) {
  548.             if(!u.ugold) pline(no_money);
  549.             else pline("Besides, you don't have enough to interest %s.",
  550.                 ESHK(shkp)->ismale ? "him" : "her");
  551.             return(1);
  552.             }
  553.             pline("But since %s shop has been robbed recently,",
  554.             ESHK(shkp)->ismale ? "his" : "her");
  555.             pline("you %scompensate %s for %s losses.",
  556.             (u.ugold < ltmp) ? "partially " : "",
  557.             mon_nam(shkp),
  558.             ESHK(shkp)->ismale ? "his" : "her");
  559.             pay(u.ugold < ltmp ? u.ugold : ltmp, shkp);
  560.             make_happy_shk(shkp);
  561.         } else {
  562.             /* shopkeeper is angry, but has not been robbed --
  563.              * door broken, attacked, etc. */
  564.             pline("%s is after your hide, not your money!",
  565.                     mon_nam(shkp));
  566.             if(u.ugold < 1000L) {
  567.             if(!u.ugold) pline(no_money);
  568.             else
  569.         pline("Besides, you don't have enough to interest %s.",
  570.                 ESHK(shkp)->ismale ? "him" : "her");
  571.             return(1);
  572.             }
  573.             You("try to appease %s by giving %s 1000 gold pieces.",
  574.                 a_monnam(shkp, "angry"),
  575.                 ESHK(shkp)->ismale ? "him" : "her");
  576.             pay(1000L,shkp);
  577.             if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)
  578.                     || rn2(3))
  579.             make_happy_shk(shkp);
  580.             else
  581.             pline("But %s is as angry as ever.", Monnam(shkp));
  582.         }
  583.         return(1);
  584.     }
  585.     if(shkp != shopkeeper) {
  586.         impossible("dopay: not to shopkeeper?");
  587.         if(shopkeeper) setpaid();
  588.         return(0);
  589.     }
  590.     /* pay debt, if any, first */
  591.     if(ESHK(shopkeeper)->debit) {
  592.             You("owe %s %ld zorkmid%s for the use of merchandise.",
  593.             shkname(shopkeeper), ESHK(shopkeeper)->debit,
  594.                 plur(ESHK(shopkeeper)->debit));
  595.             if(u.ugold + ESHK(shopkeeper)->credit < 
  596.                     ESHK(shopkeeper)->debit) {
  597.             pline("But you don't have enough gold%s.",
  598.             ESHK(shopkeeper)->credit ? " or credit" : "");
  599.             return(1);
  600.             } else {
  601.             long dtmp = ESHK(shopkeeper)->debit;
  602.  
  603.             if(ESHK(shopkeeper)->credit >= dtmp) {
  604.             ESHK(shopkeeper)->credit -= dtmp;
  605.             ESHK(shopkeeper)->debit = 0L;
  606.                     Your("debt is covered by your credit.");
  607.             } else if(!ESHK(shopkeeper)->credit) {
  608.             u.ugold -= dtmp;
  609.             shopkeeper->mgold += dtmp;
  610.             ESHK(shopkeeper)->debit = 0L;
  611.             You("pay that debt.");
  612.             flags.botl = 1;
  613.             } else {
  614.             dtmp -= ESHK(shopkeeper)->credit;
  615.             ESHK(shopkeeper)->credit = 0L;
  616.             u.ugold -= dtmp;
  617.             shopkeeper->mgold += dtmp;
  618.             ESHK(shopkeeper)->debit = 0L;
  619.             pline("That debt is partially offset by your credit.");
  620.             You("pay the remainder.");
  621.             flags.botl = 1;
  622.             }
  623.         }
  624.     }
  625.     for(pass = 0; pass <= 1; pass++) {
  626.         tmp = 0;
  627.         while(tmp < ESHK(shopkeeper)->billct) {
  628.             bp = &bill[tmp];
  629.             if(!pass && !bp->useup) {
  630.             tmp++;
  631.             continue;
  632.             }
  633.             if(!dopayobj(bp)) return(1);
  634. #ifdef MSDOS
  635.             *bp = bill[--ESHK(shopkeeper)->billct];
  636. #else
  637.             bill[tmp] = bill[--ESHK(shopkeeper)->billct];
  638. #endif /* MSDOS /**/
  639.         }
  640.     }
  641.     if(!ANGRY(shopkeeper))
  642.         pline("\"Thank you for shopping in %s's %s!\"",
  643.         shkname(shopkeeper),
  644.         shtypes[rooms[ESHK(shopkeeper)->shoproom].rtype - SHOPBASE].name);
  645.     return(1);
  646. }
  647.  
  648. /* return 1 if paid successfully */
  649. /*        0 if not enough money */
  650. /*       -1 if object could not be found (but was paid) */
  651. static int
  652. dopayobj(bp)
  653. register struct bill_x *bp;
  654. {
  655.     register struct obj *obj;
  656.     long ltmp;
  657.  
  658.     /* find the object on one of the lists */
  659.     obj = bp_to_obj(bp);
  660.  
  661.     if(!obj) {
  662.         impossible("Shopkeeper administration out of order.");
  663.         setpaid();    /* be nice to the player */
  664.         return(0);
  665.     }
  666.  
  667.     if(!obj->unpaid && !bp->useup){
  668.         impossible("Paid object on bill??");
  669.         return(1);
  670.     }
  671.     obj->unpaid = 0;
  672.     ltmp = bp->price * bp->bquan;
  673.     if(ANGRY(shopkeeper)) ltmp += ltmp/3L;
  674.     if(u.ugold + ESHK(shopkeeper)->credit < ltmp){
  675.         You("don't have gold%s enough to pay for %s.",
  676.             (ESHK(shopkeeper)->credit > 0L) ? " or credit" : "",
  677.             doname(obj));
  678.         obj->unpaid = 1;
  679.         return(0);
  680.     }
  681.     pay(ltmp, shopkeeper);
  682.     You("bought %s for %ld gold piece%s.",
  683.         doname(obj), ltmp, plur(ltmp));
  684.     if(bp->useup) {
  685.         register struct obj *otmp = billobjs;
  686.         if(obj == billobjs)
  687.             billobjs = obj->nobj;
  688.         else {
  689.             while(otmp && otmp->nobj != obj) otmp = otmp->nobj;
  690.             if(otmp) otmp->nobj = obj->nobj;
  691.             else pline("Error in shopkeeper administration.");
  692.         }
  693.         free((genericptr_t) obj);
  694.     }
  695.     return(1);
  696. }
  697.  
  698. /* routine called after dying (or quitting) with nonempty bill or upset shk */
  699. boolean
  700. paybill(){
  701.     register struct monst *mtmp, *mtmp2;
  702.     register long loss = 0L;
  703.     register struct obj *otmp;
  704.     register xchar ox, oy;
  705.     register boolean take = FALSE;
  706.     register boolean taken = FALSE;
  707.  
  708.     for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  709.         mtmp2 = mtmp->nmon;
  710.         if(mtmp->isshk) {
  711.         /* for bones: we don't want a shopless shk around */
  712.         if(ESHK(mtmp)->shoplevel != dlevel) mongone(mtmp);
  713.         else shopkeeper = mtmp;
  714.         }
  715.     }
  716.  
  717.     if(!shopkeeper) goto clear;
  718.  
  719.     /* get one case out of the way: you die in the shop, the */
  720.     /* shopkeeper is peaceful, nothing stolen, nothing owed. */
  721.     if(in_shop(u.ux,u.uy) && !IS_DOOR(levl[u.ux][u.uy].typ) &&
  722.         !ESHK(shopkeeper)->billct && !ESHK(shopkeeper)->robbed &&
  723.         !ESHK(shopkeeper)->debit && inhishop(shopkeeper) && 
  724.          NOTANGRY(shopkeeper) && !ESHK(shopkeeper)->following) {
  725.         pline("%s gratefully inherits all your possessions.",
  726.                 Monnam(shopkeeper));
  727.         goto clear;
  728.     }
  729.  
  730.     if(ESHK(shopkeeper)->billct || ESHK(shopkeeper)->debit ||
  731.             ESHK(shopkeeper)->robbed) {
  732.         addupbill();
  733.         total += ESHK(shopkeeper)->debit;
  734.         loss = ((total >= ESHK(shopkeeper)->robbed) ? total :
  735.                 ESHK(shopkeeper)->robbed);
  736.         take = TRUE;
  737.     }
  738.  
  739.     if(ESHK(shopkeeper)->following || ANGRY(shopkeeper) || take) {
  740.         if((loss > u.ugold) || !loss) {
  741.             pline("%s %sand takes all your possessions.",
  742.                 Monnam(shopkeeper), 
  743.                 (shopkeeper->msleep || shopkeeper->mfrozen) ?
  744.                 "wakes up " : "comes ");
  745.             taken = TRUE;
  746.             shopkeeper->mgold += u.ugold;
  747.             u.ugold = 0L;
  748.             /* in case bones: make it be for real... */
  749.             if(!in_shop(u.ux, u.uy) || IS_DOOR(levl[u.ux][u.uy].typ)) {
  750.                 /* shk.x,shk.y is the position immediately in
  751.                  * front of the door -- move in one more space
  752.                  */
  753.                 ox = ESHK(shopkeeper)->shk.x;
  754.                 oy = ESHK(shopkeeper)->shk.y;
  755.                 ox += sgn(ox - ESHK(shopkeeper)->shd.x);
  756.                 oy += sgn(oy - ESHK(shopkeeper)->shd.y);
  757.             } else {
  758.                 ox = u.ux;
  759.                 oy = u.uy;
  760.             }
  761.  
  762.             if (invent) {
  763.                 for(otmp = invent; otmp; otmp = otmp->nobj)
  764.                 place_object(otmp, ox, oy);
  765.  
  766.                 /* add to main object list at end so invent is
  767.                    still good */
  768.                 if (fobj) {
  769.                 otmp = fobj;
  770.                 while(otmp->nobj)
  771.                     otmp = otmp->nobj;
  772.                 otmp->nobj = invent;
  773.                 } else
  774.                 fobj = invent;
  775.             }
  776.         } else {
  777.             u.ugold -= loss;
  778.             shopkeeper->mgold += loss;
  779.             pline("%s %sand takes %ld zorkmid%s %sowed %s.",
  780.                   Monnam(shopkeeper),
  781.                   (shopkeeper->msleep || shopkeeper->mfrozen) ?
  782.                     "wakes up " : "comes ",
  783.                   loss,
  784.                   plur(loss),
  785.                   strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ) ? "" : "you ",
  786.                   ESHK(shopkeeper)->ismale ? "him" : "her");
  787.         }
  788.  
  789.         /* in case we create bones */
  790.         if(!inhishop(shopkeeper))
  791.             home_shk(shopkeeper);
  792.     }
  793. clear:
  794.     setpaid();
  795.     return(taken);
  796. }
  797.  
  798. /* find obj on one of the lists */
  799. static struct obj *
  800. bp_to_obj(bp)
  801. register struct bill_x *bp;
  802. {
  803.     register struct obj *obj;
  804.     register struct monst *mtmp;
  805.     register unsigned int id = bp->bo_id;
  806.  
  807.     if(bp->useup)
  808.         obj = o_on(id, billobjs);
  809.     else if(!(obj = o_on(id, invent)) &&
  810.         !(obj = o_on(id, fobj)) &&
  811.         !(obj = o_on(id, fcobj))) {
  812.             for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  813.             if(obj = o_on(id, mtmp->minvent))
  814.                 break;
  815.             for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
  816.             if(obj = o_on(id, mtmp->minvent))
  817.                 break;
  818.         }
  819.     return(obj);
  820. }
  821.  
  822. static unsigned
  823. get_cost(obj)
  824. register struct obj *obj;
  825. {
  826.     register unsigned tmp;
  827.  
  828.     tmp = getprice(obj);
  829.     if (!tmp) tmp = 5;
  830.     if (ANGRY(shopkeeper) || 
  831.         (pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))
  832. #ifdef SHIRT
  833.         || (uarmu && !uarm) /* wearing just a Hawaiian shirt */
  834. #endif
  835.        )
  836.         tmp += tmp/3;
  837.     if (ACURR(A_CHA) > 18)        tmp /= 2;
  838.     else if (ACURR(A_CHA) > 17)    tmp = (tmp * 2)/3;
  839.     else if (ACURR(A_CHA) > 15)    tmp = (tmp * 3)/4;
  840.     else if (ACURR(A_CHA) < 6)    tmp *= 2;
  841.     else if (ACURR(A_CHA) < 8)    tmp = (tmp * 3)/2;
  842.     else if (ACURR(A_CHA) < 11)    tmp = (tmp * 4)/3;
  843.     if (!tmp) return 1;
  844.     return(tmp);
  845. }
  846.  
  847.  
  848. /* called in hack.c when we pickup an object */
  849. void
  850. addtobill(obj, ininv)
  851. register struct obj *obj;
  852. register boolean ininv;
  853. {
  854.     register struct bill_x *bp;
  855.     char    buf[40];
  856.     if(!shopkeeper || !inhishop(shopkeeper)) return;
  857.  
  858.     if(!costly_spot(obj->ox,obj->oy) ||    /* either pickup or kick */
  859.         onbill(obj) /* perhaps we threw it away earlier */
  860.           ) return;
  861.     if(ESHK(shopkeeper)->billct == BILLSZ) {
  862.         You("got that for free!");
  863.         return;
  864.     }
  865.     /* To recognize objects the shopkeeper is not interested in. -dgk
  866.      */
  867.     if (obj->no_charge) {
  868.         obj->no_charge = 0;
  869.         return;
  870.     }
  871.     bp = &bill[ESHK(shopkeeper)->billct];
  872.     bp->bo_id = obj->o_id;
  873.     bp->bquan = obj->quan;
  874.     bp->useup = 0;
  875.     bp->price = get_cost(obj);
  876.     if(!shopkeeper->msleep && !shopkeeper->mfrozen) {
  877.         Strcpy(buf, "\"For you, ");
  878.         if (ANGRY(shopkeeper)) Strcat(buf, "scum ");
  879.         else {
  880.             switch(rnd(4)
  881. #ifdef HARD
  882.            + u.udemigod
  883. #endif
  884.                 ) {
  885.         case 1:    Strcat(buf, "good");
  886.             break;
  887.         case 2:    Strcat(buf, "honored");
  888.             break;
  889.         case 3:    Strcat(buf, "most gracious");
  890.             break;
  891.         case 4:    Strcat(buf, "esteemed");
  892.             break;
  893.         case 5: if (u.ualigntyp == U_CHAOTIC) Strcat(buf, "un");
  894.             Strcat(buf, "holy");
  895.             break;
  896.             }
  897. #ifdef POLYSELF
  898.             if(!is_human(uasmon)) Strcat(buf, " creature");
  899.             else
  900. #endif
  901.             Strcat(buf, (flags.female) ? " lady" : " sir");
  902.         }
  903.         obj->dknown = 1; /* after all, the shk is telling you what it is */
  904.         if(ininv) {
  905.         obj->quan = 1; /* fool xname() into giving singular */
  906.         pline("%s; only %d %s %s.\"", buf, bp->price,
  907.             (bp->bquan > 1) ? "per" : "for this", xname(obj));
  908.         obj->quan = bp->bquan;
  909.         } else pline("The %s will cost you %d zorkmid%s%s.",
  910.             xname(obj), bp->price, plur((long)bp->price),
  911.             (bp->bquan > 1) ? " each" : "");
  912.     } else pline("The list price of %s is %d zorkmid%s%s.",
  913.             xname(obj), bp->price, plur((long)bp->price),
  914.             (bp->bquan > 1) ? " each" : "");
  915.     ESHK(shopkeeper)->billct++;
  916.     obj->unpaid = 1;
  917. }
  918.  
  919. void
  920. splitbill(obj, otmp)
  921. register struct obj *obj, *otmp;
  922. {
  923.     /* otmp has been split off from obj */
  924.     register struct bill_x *bp;
  925.     register int tmp;
  926.     bp = onbill(obj);
  927.     if(!bp) {
  928.         impossible("splitbill: not on bill?");
  929.         return;
  930.     }
  931.     if(bp->bquan < otmp->quan) {
  932.         impossible("Negative quantity on bill??");
  933.     }
  934.     if(bp->bquan == otmp->quan) {
  935.         impossible("Zero quantity on bill??");
  936.     }
  937.     bp->bquan -= otmp->quan;
  938.  
  939.     if(ESHK(shopkeeper)->billct == BILLSZ) otmp->unpaid = 0;
  940.     else {
  941.         tmp = bp->price;
  942.         bp = &bill[ESHK(shopkeeper)->billct];
  943.         bp->bo_id = otmp->o_id;
  944.         bp->bquan = otmp->quan;
  945.         bp->useup = 0;
  946.         bp->price = tmp;
  947.         ESHK(shopkeeper)->billct++;
  948.     }
  949. }
  950.  
  951. void
  952. subfrombill(obj)
  953. register struct obj *obj;
  954. {
  955.     register struct bill_x *bp;
  956.  
  957.     if(!shopkeeper) return;
  958.  
  959.     if((bp = onbill(obj)) != 0) {
  960.         register struct obj *otmp;
  961.  
  962.         obj->unpaid = 0;
  963.         if(bp->bquan > obj->quan){
  964.             otmp = newobj(0);
  965.             *otmp = *obj;
  966.             bp->bo_id = otmp->o_id = flags.ident++;
  967.             otmp->quan = (bp->bquan -= obj->quan);
  968.             otmp->owt = 0;    /* superfluous */
  969.             otmp->onamelth = 0;
  970.             bp->useup = 1;
  971.             otmp->nobj = billobjs;
  972.             billobjs = otmp;
  973.             return;
  974.         }
  975.         ESHK(shopkeeper)->billct--;
  976.         *bp = bill[ESHK(shopkeeper)->billct];
  977.         return;
  978.     } else if (obj->unpaid) {
  979.         impossible("subfrombill: unpaid object not on bill");
  980.         obj->unpaid = 0;
  981.     }
  982. }
  983.  
  984. void
  985. sellobj(obj)
  986. register struct obj *obj;
  987. {
  988.     long ltmp;
  989.  
  990.     if(!costly_spot(u.ux,u.uy))
  991.         return;
  992.     if(obj->unpaid) {
  993.         subfrombill(obj);
  994.         return;
  995.     }
  996.     /* you dropped something of your own - probably want to sell it */
  997.     if(shopkeeper->msleep || !shopkeeper->mcanmove || !inhishop(shopkeeper))
  998.         return;
  999.     ltmp = (long) getprice(obj) * (long) obj->quan;
  1000.     if (ANGRY(shopkeeper) || (pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))
  1001. #ifdef SHIRT
  1002.         || (uarmu && !uarm) /* wearing just a Hawaiian shirt */
  1003. #endif
  1004.        ) {
  1005.         ltmp /= 3L;
  1006.         NOTANGRY(shopkeeper) = 1;
  1007.     } else    ltmp /= 2L;
  1008.     if(ESHK(shopkeeper)->billct == BILLSZ
  1009.        || !saleable(rooms[ESHK(shopkeeper)->shoproom].rtype-SHOPBASE, obj)
  1010.        || obj->olet == BALL_SYM || ltmp == 0L
  1011.        || (obj->olet == FOOD_SYM && obj->oeaten)) {
  1012.         pline("%s seems not interested.", Monnam(shopkeeper));
  1013.         obj->no_charge = 1;
  1014.         return;
  1015.     }
  1016.     if(ESHK(shopkeeper)->robbed) {
  1017.         if((ESHK(shopkeeper)->robbed -= ltmp) < 0L)
  1018.             ESHK(shopkeeper)->robbed = 0L;
  1019. verbalize("Thank you for your contribution to restock this recently plundered shop.");
  1020.         return;
  1021.     }
  1022.     if(ltmp > shopkeeper->mgold)
  1023.         ltmp = shopkeeper->mgold;
  1024.     pay(-ltmp, shopkeeper);
  1025.     if(!ltmp) {
  1026.         pline("%s gladly accepts %s but cannot pay you at present.",
  1027.             Monnam(shopkeeper), doname(obj));
  1028.             obj->no_charge = 1;
  1029.     } else
  1030.     You("sold %s for %ld gold piece%s.", doname(obj), ltmp,
  1031.         plur(ltmp));
  1032. }
  1033.  
  1034. int
  1035. doinvbill(mode)
  1036. int mode;        /* 0: deliver count 1: paged */
  1037. {
  1038.     register struct bill_x *bp;
  1039.     register struct obj *obj;
  1040. #ifdef __GNULINT__
  1041.     long totused, thisused = 0L;
  1042. /* possibly a bug in the GCC; clearly thisused is always set before use */
  1043. #else
  1044.     long totused, thisused;
  1045. #endif
  1046.     char buf[BUFSZ];
  1047.  
  1048.     if(mode == 0) {
  1049.         register int cnt = 0;
  1050.  
  1051.         if(shopkeeper)
  1052.         for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++)
  1053.             if(bp->useup ||
  1054.               ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan))
  1055.             cnt++;
  1056.         return(cnt);
  1057.     }
  1058.  
  1059.     if(!shopkeeper) {
  1060.         impossible("doinvbill: no shopkeeper?");
  1061.         return(0);
  1062.     }
  1063.  
  1064.     set_pager(0);
  1065.     if(page_line("Unpaid articles already used up:") || page_line(""))
  1066.         goto quit;
  1067.  
  1068.     totused = 0L;
  1069.     for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) {
  1070.         obj = bp_to_obj(bp);
  1071.         if(!obj) {
  1072.         impossible("Bad shopkeeper administration.");
  1073.         goto quit;
  1074.         }
  1075.         if(bp->useup || bp->bquan > obj->quan) {
  1076.         register int cnt;
  1077.         register unsigned oquan, uquan;
  1078.  
  1079.         oquan = obj->quan;
  1080.         uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
  1081.         thisused = bp->price * uquan;
  1082.         totused += thisused;
  1083.         obj->quan = uquan;        /* cheat doname */
  1084.         Sprintf(buf, "x -  %s", doname(obj));
  1085.         obj->quan = oquan;        /* restore value */
  1086.         for(cnt = 0; buf[cnt]; cnt++);
  1087.         while(cnt < 50)
  1088.             buf[cnt++] = ' ';
  1089.         Sprintf(&buf[cnt], " %5ld zorkmid%s", thisused, plur(thisused));
  1090.         if(page_line(buf))
  1091.             goto quit;
  1092.         }
  1093.     }
  1094.     Sprintf(buf, "Total:%50ld zorkmid%s", totused, plur(totused));
  1095.     if(page_line("") || page_line(buf))
  1096.         goto quit;
  1097.     set_pager(1);
  1098.     return(0);
  1099. quit:
  1100.     set_pager(2);
  1101.     return(0);
  1102. }
  1103.  
  1104. #define HUNGRY    2
  1105. static int
  1106. getprice(obj)
  1107. register struct obj *obj;
  1108. {
  1109.     register int tmp = objects[obj->otyp].oc_cost;
  1110.  
  1111.     switch(obj->olet) {
  1112.     case AMULET_SYM:
  1113.         if(obj->otyp == AMULET_OF_YENDOR) {
  1114.             /* don't let the player get rich selling fakes */
  1115.             tmp = (obj->spe < 0 ? 0 : 3500);
  1116.         }
  1117.         break;
  1118.     case FOOD_SYM:
  1119.         /* simpler hunger check, (2-4)*cost */
  1120.         if (u.uhs >= HUNGRY) tmp *= u.uhs;
  1121.         if (obj->oeaten) tmp = eaten_stat(tmp, obj); /* partly eaten */
  1122.         break;
  1123.     case WAND_SYM:
  1124.         if (obj->spe == -1) tmp = 0;
  1125.         break;
  1126.     case POTION_SYM:
  1127.         if (obj->otyp == POT_WATER && !obj->blessed && !obj->cursed)
  1128.             tmp = 0;
  1129.         break;
  1130.     case ARMOR_SYM:
  1131.     case WEAPON_SYM:
  1132.         if (obj->spe > 0) tmp += 10 * obj->spe;
  1133.         break;
  1134.     case CHAIN_SYM:
  1135.         pline("Strange... carrying a chain?");
  1136.         break;
  1137.     }
  1138.     return(tmp);
  1139. }
  1140.  
  1141. int
  1142. shkcatch(obj)
  1143. register struct obj *obj;
  1144. {
  1145.     register struct monst *shkp = shopkeeper;
  1146.  
  1147.     if(obj->otyp != PICK_AXE) return(0);
  1148.     if(u.uinshop && shkp && shkp->mcanmove && !shkp->msleep &&
  1149.         inroom(u.ux+u.dx, u.uy+u.dy) + 1 == u.uinshop &&
  1150.         shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y &&
  1151.         u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y) {
  1152.         pline("%s nimbly catches the %s.", Monnam(shkp), xname(obj));
  1153.         obj->nobj = shkp->minvent;
  1154.         shkp->minvent = obj;
  1155.         subfrombill(obj);
  1156.         return(1);
  1157.     }
  1158.     return(0);
  1159. }
  1160.  
  1161. /*
  1162.  * shk_move: return 1: he moved  0: he didn't  -1: let m_move do it  -2: died
  1163.  */
  1164. int
  1165. shk_move(shkp)
  1166. register struct monst *shkp;
  1167. {
  1168.     register xchar gx,gy,omx,omy;
  1169.     register int udist;
  1170.     register schar appr;
  1171.     int z;
  1172.     schar shkroom;
  1173.     boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv;
  1174.  
  1175.     omx = shkp->mx;
  1176.     omy = shkp->my;
  1177.  
  1178.     if((udist = dist(omx,omy)) < 3 &&
  1179.        (shkp->data != &mons[PM_GRID_BUG] || (omx==u.ux || omy==u.uy))) {
  1180.         if(ANGRY(shkp)) {
  1181.             if(Displaced)
  1182.               Your("displaced image doesn't fool %s!",
  1183.                 Monnam(shkp));
  1184.             (void) mattacku(shkp);
  1185.             return(0);
  1186.         }
  1187.         if(ESHK(shkp)->following) {
  1188.             if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)) {
  1189.                 pline("\"Hello, %s!  I was looking for %s.\"",
  1190.                     plname, ESHK(shkp)->customer);
  1191.                     ESHK(shkp)->following = 0;
  1192.                 return(0);
  1193.             }
  1194.             if(moves > followmsg+4) {
  1195.                 pline("\"Hello, %s!  Didn't you forget to pay?\"",
  1196.                     plname);
  1197.                 followmsg = moves;
  1198. #ifdef HARD
  1199.                 if (!rn2(4)) {
  1200.         pline ("%s doesn't like customers who don't pay.", Monnam(shkp));
  1201.                 NOTANGRY(shkp) = 0;
  1202.                 }
  1203. #endif
  1204.             }
  1205.             if(udist < 2)
  1206.                 return(0);
  1207.         }
  1208.     }
  1209.  
  1210.     shkroom = inroom(omx,omy);
  1211.     appr = 1;
  1212.     gx = ESHK(shkp)->shk.x;
  1213.     gy = ESHK(shkp)->shk.y;
  1214.     satdoor = (gx == omx && gy == omy);
  1215.     if(ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){
  1216.         gx = u.ux;
  1217.         gy = u.uy;
  1218.         if(shkroom < 0 || shkroom != inroom(u.ux,u.uy))
  1219.             if(udist > 4)
  1220.             return(-1);    /* leave it to m_move */
  1221.     } else if(ANGRY(shkp)) {
  1222.         long saveBlind = Blinded;
  1223.         struct obj *saveUblindf = ublindf;
  1224.         Blinded = 0;
  1225.         ublindf = (struct obj *)0;
  1226.         if(shkp->mcansee && !Invis && cansee(omx,omy)) {
  1227.             gx = u.ux;
  1228.             gy = u.uy;
  1229.         }
  1230.         Blinded = saveBlind;
  1231.         ublindf = saveUblindf;
  1232.         avoid = FALSE;
  1233.     } else {
  1234. #define    GDIST(x,y)    (dist2(x,y,gx,gy))
  1235.         if(Invis)
  1236.             avoid = FALSE;
  1237.         else {
  1238.             uondoor = (u.ux == ESHK(shkp)->shd.x &&
  1239.                 u.uy == ESHK(shkp)->shd.y);
  1240.             if(uondoor) {
  1241.             if((ESHK(shkp)->billct || ESHK(shkp)->debit) 
  1242.                     && inhishop(shkp))
  1243.                 pline(NOTANGRY(shkp) ?
  1244.                 "\"Hello, %s!  Will you please pay before leaving?\"" :
  1245.                 "\"Hey, %s!  Don't leave without paying!\"",
  1246.                 plname);
  1247.             badinv = (!!carrying(PICK_AXE));
  1248.             if(satdoor && badinv)
  1249.                 return(0);
  1250.             avoid = !badinv;
  1251.             } else {
  1252.             avoid = (u.uinshop && dist(gx,gy) > 8);
  1253.             badinv = FALSE;
  1254.             }
  1255.  
  1256.             if(((!ESHK(shkp)->robbed && !ESHK(shkp)->billct &&
  1257.                 !ESHK(shkp)->debit) || avoid)
  1258.             && GDIST(omx,omy) < 3) {
  1259.             if(!badinv && !online(omx,omy))
  1260.                 return(0);
  1261.             if(satdoor)
  1262.                 appr = gx = gy = 0;
  1263.             }
  1264.         }
  1265.     }
  1266.     
  1267.     return(move_special(shkp,shkroom,appr,uondoor,avoid,omx,omy,gx,gy));
  1268. }
  1269.  
  1270. #endif /* OVLB */
  1271. #ifdef OVL0
  1272.  
  1273. int
  1274. online(x,y)        /*    New version to speed things up.
  1275.              *    Compiler dependant, may not always work.
  1276.              */
  1277. register xchar x, y;
  1278. {
  1279.     return((x-=u.ux) == 0 || (y-=u.uy) == 0 || x == y || (x+=y) == 0);
  1280. }
  1281.  
  1282. /*            Original version, just in case...
  1283.  *online(x,y) {
  1284.  *    return(x==u.ux || y==u.uy || (x-u.ux)*(x-u.ux) == (y-u.uy)*(y-u.uy));
  1285.  *}
  1286.  */
  1287.  
  1288. #endif /* OVL0 */
  1289. #ifdef OVLB
  1290.  
  1291. /* for use in levl_follower (mondata.c) */
  1292. boolean
  1293. is_fshk(mtmp)
  1294. register struct monst *mtmp;
  1295. {
  1296.     return(mtmp->isshk && ESHK(mtmp)->following);
  1297. }
  1298.  
  1299. /* He is digging in the shop. */
  1300. void
  1301. shopdig(fall)
  1302. register int fall;
  1303. {
  1304.     if(!shopkeeper) return;
  1305.     if(!inhishop(shopkeeper)) {
  1306.     if (pl_character[0] == 'K') adjalign(-sgn(u.ualigntyp));
  1307.     return;
  1308.     }
  1309.  
  1310.     if(!fall) {
  1311.     if(u.utraptype == TT_PIT)
  1312.         pline("\"Be careful, %s, or you might fall through the floor.\"",
  1313.         flags.female ? "madam" : "sir");
  1314.     else
  1315.         pline("\"%s, do not damage the floor here!\"",
  1316.             flags.female ? "Madam" : "Sir");
  1317.     if (pl_character[0] == 'K') adjalign(-sgn(u.ualigntyp));
  1318.     } else 
  1319.     if(!um_dist(shopkeeper->mx, shopkeeper->my, 5) &&
  1320.           !shopkeeper->msleep && shopkeeper->mcanmove &&
  1321.           (ESHK(shopkeeper)->billct || ESHK(shopkeeper)->debit)) {
  1322.         register struct obj *obj, *obj2;
  1323.  
  1324.         if(dist(shopkeeper->mx, shopkeeper->my) > 2) {
  1325.         mnexto(shopkeeper);
  1326.         /* for some reason he can't come next to you */
  1327.         if(dist(shopkeeper->mx, shopkeeper->my) > 2) {
  1328.             pline("%s curses you in anger and frustration!",
  1329.                     shkname(shopkeeper));
  1330.             NOTANGRY(shopkeeper) = 0;
  1331.             return;
  1332.         } else pline("%s leaps, and grabs your backpack!",
  1333.                     shkname(shopkeeper));
  1334.         } else pline("%s grabs your backpack!", shkname(shopkeeper));
  1335.  
  1336.         for(obj = invent; obj; obj = obj2) {
  1337.         obj2 = obj->nobj;
  1338.         if(obj->owornmask) continue;
  1339. #ifdef WALKIES
  1340.         if(obj->otyp == LEASH && obj->leashmon) continue;
  1341. #endif
  1342.         freeinv(obj);
  1343.         obj->nobj = shopkeeper->minvent;
  1344.         shopkeeper->minvent = obj;
  1345.         subfrombill(obj);
  1346.         }
  1347.     }
  1348. }
  1349.  
  1350. #ifdef KOPS
  1351. STATIC_OVL int
  1352. makekops(mm)        /* returns the number of (all types of) Kops  made */
  1353. coord *mm;
  1354. {
  1355.     register int cnt = dlevel + rnd(5);
  1356.     register int scnt = (cnt / 3) + 1;    /* at least one sarge */
  1357.     register int lcnt = (cnt / 6);        /* maybe a lieutenant */
  1358.     register int kcnt = (cnt / 9);        /* and maybe a kaptain */
  1359.  
  1360.     while(cnt--) {
  1361.         if (enexto(mm, mm->x, mm->y, &mons[PM_KEYSTONE_KOP]))
  1362.             (void) makemon(&mons[PM_KEYSTONE_KOP], mm->x, mm->y);
  1363.     }
  1364.     while(scnt--) {
  1365.         if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_SERGEANT]))
  1366.             (void) makemon(&mons[PM_KOP_SERGEANT], mm->x, mm->y);
  1367.     }
  1368.     while(lcnt--) {
  1369.         if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_LIEUTENANT]))
  1370.             (void) makemon(&mons[PM_KOP_LIEUTENANT], mm->x, mm->y);
  1371.     }
  1372.     while(kcnt--) {
  1373.         if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_KAPTAIN]))
  1374.             (void) makemon(&mons[PM_KOP_KAPTAIN], mm->x, mm->y);
  1375.     }
  1376.     return(cnt + scnt + lcnt + kcnt);
  1377. }
  1378. #endif
  1379.  
  1380. #endif /* OVLB */
  1381. #ifdef OVL1
  1382.  
  1383. boolean
  1384. in_shop(x,y)
  1385. register int x, y;
  1386. {
  1387.     register int roomno = inroom(x, y);
  1388.  
  1389.     if (roomno < 0) return(FALSE);
  1390.     return (IS_SHOP(rooms[roomno]));
  1391. }
  1392.  
  1393. #endif /* OVL1 */
  1394. #ifdef OVLB
  1395.  
  1396. void
  1397. pay_for_door(x,y,dmgstr)
  1398. int x, y;
  1399. const char *dmgstr;
  1400. {
  1401.     struct monst *mtmp;
  1402.     int roomno = inroom(x, y);
  1403.     long damage;
  1404.     boolean uinshp = in_shop(u.ux, u.uy);
  1405.  
  1406.     /* make sure this function is not used in the wrong place */
  1407.     if(!(IS_DOOR(levl[x][y].typ) && in_shop(x, y))) return;
  1408.  
  1409.     findshk(roomno);
  1410.  
  1411.     if(!shopkeeper) return;
  1412.  
  1413.     /* not the best introduction to the shk... */
  1414.     (void) strncpy(ESHK(shopkeeper)->customer,plname,PL_NSIZ);
  1415.  
  1416.     /* if he is already on the war path, be sure it's all out */
  1417.     if(ANGRY(shopkeeper) || ESHK(shopkeeper)->following) {
  1418.         NOTANGRY(shopkeeper) = 0;
  1419.         ESHK(shopkeeper)->following = 1;
  1420.         return;
  1421.     }
  1422.  
  1423.     /* if he's not in his shop.. */
  1424.     if(!in_shop(shopkeeper->mx ,shopkeeper->my)) {
  1425.         if(!cansee(shopkeeper->mx, shopkeeper->my)) return;
  1426.         goto gethim;
  1427.     }
  1428.  
  1429.     if(uinshp) {
  1430.         if(um_dist(shopkeeper->mx, shopkeeper->my, 1) &&
  1431.                !um_dist(shopkeeper->mx, shopkeeper->my, 3)) { 
  1432.             pline("%s leaps towards you!", shkname(shopkeeper));
  1433.             mnexto(shopkeeper);
  1434.         }
  1435.         if(um_dist(shopkeeper->mx, shopkeeper->my, 1)) goto gethim;
  1436.     } else {
  1437.         /* if a !shopkeeper shows up at the door, move him */
  1438.         if((mtmp = m_at(x, y)) && mtmp != shopkeeper) {
  1439.         if(flags.soundok) {
  1440.             You("hear an angry voice:");
  1441.             verbalize("Out of my way, scum!");
  1442.             (void) fflush(stdout);
  1443. #if defined(SYSV) || defined(ULTRIX) || defined(VMS)
  1444.             (void)
  1445. #endif
  1446. #if defined(UNIX) || defined(VMS)
  1447.             sleep(1);
  1448. #endif
  1449.         }
  1450.         mnearto(mtmp, x, y, FALSE);
  1451.         }
  1452.  
  1453.         /* make shk show up at the door */
  1454.         remove_monster(shopkeeper->mx, shopkeeper->my);
  1455.         place_monster(shopkeeper, x, y);
  1456.         pmon(shopkeeper);
  1457.     }
  1458.  
  1459.     if(!strcmp(dmgstr, "destroy")) damage = 400L;
  1460.     else damage = (long)(ACURR(A_STR) > 18) ? 400 : 20 * ACURR(A_STR);
  1461.  
  1462.     if((um_dist(x, y, 1) && !uinshp) || 
  1463.             (u.ugold + ESHK(shopkeeper)->credit) < damage 
  1464.                 || !rn2(50)) {
  1465.         if(um_dist(x, y, 1) && !uinshp) {
  1466.             pline("%s shouts:", shkname(shopkeeper));
  1467.             pline("\"Who dared %s my door?\"", dmgstr);
  1468.         } 
  1469.         else
  1470. gethim:
  1471.             pline("\"How dare you %s my door?\"", dmgstr);
  1472.  
  1473.         NOTANGRY(shopkeeper) = 0;
  1474.         ESHK(shopkeeper)->following = 1;
  1475.         return;
  1476.     }
  1477.  
  1478.     if(Invis) Your("invisibility does not fool %s!", shkname(shopkeeper));
  1479.     pline("\"Cad!  You did %ld zorkmids worth of damage!\"  Pay? ", damage);
  1480.     if(yn() != 'n') {
  1481.         damage = check_credit(damage, shopkeeper);
  1482.         u.ugold -= damage;
  1483.         shopkeeper->mgold += damage;
  1484.         flags.botl = 1;
  1485.         pline("Mollified, %s accepts your restitution.",
  1486.             shkname(shopkeeper));
  1487.         /* move shk back to his home loc */
  1488.         home_shk(shopkeeper);
  1489.         NOTANGRY(shopkeeper) = 1;
  1490.     } else {
  1491.         verbalize("Oh, yes!  You'll pay!");
  1492.         ESHK(shopkeeper)->following = 1;
  1493.         NOTANGRY(shopkeeper) = 0;
  1494.         adjalign(-sgn(u.ualigntyp));
  1495.     }
  1496. }
  1497.  
  1498. /* called in dokick.c when we kick an object in a store */
  1499. boolean
  1500. costly_spot(x, y)
  1501. register int x, y;
  1502. {
  1503.     register struct monst *shkp = shopkeeper;
  1504.     
  1505.     if(!shkp) return(FALSE);
  1506.  
  1507.     return(in_shop(x, y) && levl[x][y].typ != DOOR &&
  1508.         !(x == ESHK(shkp)->shk.x && y == ESHK(shkp)->shk.y));
  1509. }
  1510.  
  1511. #ifdef KOPS
  1512. static void
  1513. kops_gone()
  1514. {
  1515.     register int cnt = 0;
  1516.     register struct monst *mtmp, *mtmp2;
  1517.  
  1518.     /* turn off automatic resurrection of kops */
  1519.     allow_kops = FALSE;
  1520.  
  1521.     for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  1522.         mtmp2 = mtmp->nmon;
  1523.         if(mtmp->data->mlet == S_KOP) {
  1524.             mongone(mtmp);
  1525.             cnt++;
  1526.         }
  1527.     }
  1528.     if(cnt) pline("The Kops (disappointed) disappear into thin air.");
  1529.     allow_kops = TRUE;
  1530. }
  1531. #endif
  1532.  
  1533. static unsigned
  1534. cost_per_charge(otmp)
  1535. register struct obj *otmp;
  1536. {
  1537.     register unsigned tmp = get_cost(otmp);
  1538.  
  1539.     /* The idea is to make the exhaustive use of */
  1540.     /* an unpaid item more expensive than buying */
  1541.     /* outright.                     */
  1542.     if(otmp->otyp == MAGIC_LAMP) {             /* 1 */
  1543.         tmp += (tmp/3);
  1544.     } else if(otmp->otyp == MAGIC_MARKER) {       /* 70 - 100 */
  1545.         /* no way to determine in advance   */
  1546.         /* how many charges will be wasted. */
  1547.         /* so, arbitrarily, one half of the */
  1548.         /* price per use.            */
  1549.         tmp = (tmp/2);
  1550.     } else if(otmp->otyp == BAG_OF_TRICKS) {      /* 1 - 20 */
  1551.         tmp = (tmp/5);
  1552.     } else if(otmp->otyp == CRYSTAL_BALL ||       /* 1 - 5 */
  1553.           otmp->otyp == LAMP ||                     /* 1-10 */
  1554. #ifdef MUSIC
  1555.          (otmp->otyp >= MAGIC_FLUTE &&
  1556.           otmp->otyp <= DRUM_OF_EARTHQUAKE) ||      /* 5 - 9 */
  1557. #endif
  1558.             otmp->olet == WAND_SYM) {         /* 3 - 11 */
  1559.         if(otmp->spe > 1) tmp = (tmp/4);
  1560.     }
  1561.     else return(0);
  1562.     return(tmp);
  1563. }
  1564.  
  1565. /* for using charges of unpaid objects */
  1566. void
  1567. check_unpaid(otmp)
  1568. register struct obj *otmp;
  1569. {
  1570.     if(!in_shop(u.ux, u.uy)) return;
  1571.     
  1572.     if(otmp->spe <= 0) return;
  1573.  
  1574.     if(otmp->unpaid) {
  1575.         ESHK(shopkeeper)->debit += cost_per_charge(otmp);
  1576.     }
  1577. }
  1578.  
  1579. boolean
  1580. block_door(x,y)      /* used in domove to block diagonal shop-exit */
  1581. register int x, y;
  1582. {
  1583.     register int roomno = inroom(x, y);
  1584.  
  1585.     if(!in_shop(u.ux, u.uy)) return(FALSE);
  1586.  
  1587.     if(!IS_DOOR(levl[x][y].typ)) return(FALSE);
  1588.  
  1589.     if(roomno != inroom(u.ux,u.uy)) return(FALSE);
  1590.  
  1591.     findshk(roomno);
  1592.  
  1593.     if(inhishop(shopkeeper)
  1594.         && shopkeeper->mx == ESHK(shopkeeper)->shk.x
  1595.         && shopkeeper->my == ESHK(shopkeeper)->shk.y
  1596.         /* Actually, the shk should be made to block _any_ */
  1597.         /* door, including a door the player digs, if the  */
  1598.         /* shk is within a 'jumping' distance.           */
  1599.         && ESHK(shopkeeper)->shd.x == x && ESHK(shopkeeper)->shd.y == y
  1600.         && shopkeeper->mcanmove && !shopkeeper->msleep
  1601.         && (ESHK(shopkeeper)->debit || ESHK(shopkeeper)->billct ||
  1602.         ESHK(shopkeeper)->robbed)) {
  1603.         pline("%s%s blocks your way!", shkname(shopkeeper),
  1604.                 Invis ? " senses your motion and" : "");
  1605.         return(TRUE);
  1606.     }
  1607.     return(FALSE);
  1608. }
  1609.  
  1610. boolean
  1611. block_entry(x,y)      /* used in domove to block diagonal shop-entry */
  1612. register int x, y;
  1613. {
  1614.     register int sx, sy, roomno = inroom(x, y);
  1615.  
  1616.     if(roomno != inroom(u.ux,u.uy)) return(FALSE);
  1617.  
  1618.     if(!(in_shop(u.ux, u.uy) && IS_DOOR(levl[u.ux][u.uy].typ) &&
  1619.         levl[u.ux][u.uy].doormask == D_BROKEN)) return(FALSE);
  1620.  
  1621.     findshk(roomno);
  1622.     if(!inhishop(shopkeeper)) return(FALSE);
  1623.  
  1624.     if(ESHK(shopkeeper)->shd.x != u.ux || ESHK(shopkeeper)->shd.y != u.uy)
  1625.         return(FALSE);
  1626.  
  1627.     sx = ESHK(shopkeeper)->shk.x;
  1628.     sy = ESHK(shopkeeper)->shk.y;
  1629.  
  1630.     if(shopkeeper->mx == sx && shopkeeper->my == sy
  1631.             && shopkeeper->mcanmove && !shopkeeper->msleep
  1632.             && in_shop(x, y)
  1633.             && (x == sx-1 || x == sx+1 || y == sy-1 || y == sy+1)  
  1634.             && (Invis || carrying(PICK_AXE))
  1635.           ) {
  1636.         pline("%s%s blocks your way!", shkname(shopkeeper),
  1637.                 Invis ? " senses your motion and" : "");
  1638.         return(TRUE);
  1639.     }
  1640.     return(FALSE);
  1641. }
  1642.  
  1643. #endif /* OVLB */
  1644.